package com.auqaoasis.model;

import com.auqaoasis.exception.DbException;
import com.auqaoasis.model.page.Page;
import com.auqaoasis.model.page.PageID;
import com.auqaoasis.model.row.Row;
import com.auqaoasis.model.table.Table;

import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @Author Auqaoasis
 * @Date 2022/3/30 - 13:22
 * @Description: 数据库对象
 */
public class DataBase {
    private static AtomicReference<DataBase> singleton = new AtomicReference<DataBase>(new DataBase());

    /**
     * 数据库用hashmap存多张表
     */
    private HashMap<Integer, Table> id2Table;
    private HashMap<String, Table> name2Table;

    public DataBase() {
        this.id2Table = new HashMap<>();
        this.name2Table = new HashMap<>();
    }

    public static DataBase getInstance() {
        return singleton.get();
    }

    public void addTable(Table table) {
        id2Table.put(table.getHeapTableFile().getTableId(), table);
        name2Table.put(table.getTableName(), table);
    }

    public HashMap<Integer, Table> getTablesById() {
        return id2Table;
    }
    public HashMap<String, Table> getTablesByName() {
        return name2Table;
    }

    public Table getTableById(int tableId) {
        Table table = id2Table.get(tableId);
        if (table == null) {
            throw new DbException("table not exist");
        }
        return table;
    }
    public Table getTableByName(String name) {
        Table dbTable = name2Table.get(name);
        if (dbTable == null) {
            throw new DbException("table not exist");
        }
        return dbTable;
    }
    public void insertRow(Row row, String tableName) throws IOException {
        this.getTableByName(tableName).insertRow(row);
    }

    /**
     * 根据页ID获取页
     * @param pageID
     * @return
     * @throws DbException
     */
    public Page getPage(PageID pageID) throws DbException {
        try {
            return this.getTableById(pageID.getTableId()).getHeapTableFile().readPageFromDisk(pageID);
        } catch (IOException e) {
            throw new DbException("read page failed", e);
        }
    }
}
